XcodeのDevelopment Assetsを使ってSwiftUIプレビューを実装する
SwiftUIを使ってiOSアプリを開発する際に、デザインの確認のためにプレビュー機能を使用している。本記事では、Xcodeの機能である「Development Assets」を使って、プレビュー専用データをSwiftUIプレビューに表示する方法を紹介する。
Development Assetsとは
Development Assetsは、Xcodeの機能の一つである。デバッグ実行時やプレビューなど、開発中のみに必要な(リリース時には不要な)リソースやソースコードを管理して、アプリをアーカイブする際にはそれらを除外する。この機能によって、プレビューなどの開発用リソースと本番リソースの分離ができ、リリースビルドには不要なファイルが含まないようにできる。
Development Assetsの設定方法
いつから追加された機能であるかは記憶にないが、最近のXcodeでは新規にプロジェクトを作成するとDevelopment Assetsが設定済みである。既存のアプリに対してDevelopment Assetsを追加したい場合には以下の手順をおこなう。
Preview Content
グループを作成する。- プロジェクトナビゲータでターゲットを選択する。
- Generalタブを開く。
- 最下部にスクロールして、
Development Assets
の項目を探す。 - 設定フィールドに
{プロジェクト名}/Preview Content
とグループを選択する - 指定したディレクトリに、プレビュー時に必要なリソースやソースコードを配置する。
Preview Content
グループには、開発中に使用するリソースを配置しておこう。後述しているが、プレビュー専用のデータを扱う PreviewItems ファイルを Preview Content に追加している。
Development Assetsを使って効率よくSwiftUIプレビューを実装する
次に、SwiftUIのプレビュー専用のデータを管理する方法を見ていこう。あまり実用的ではないが説明用に Item
というクラスを用意する。アプリ上では name
を表示させるということにしておく (説明は後述)。
struct Item {
let name: String
}
プレビュー専用のデータを作成する
Preview Content
フォルダ内にプレビュー専用のアイテムを定義するファイルを作成した。ここでは、プレビュー用に PreviewItems
というenum
を使用して、staticなプロパティとしてプレビュー用のアイテムを定義している。
import Foundation
enum PreviewItems {
static let previewItem1 = Item(
name: "プレビュー用のアイテム"
)
余談だが、列挙子がないのに enum を使っていると驚く方がいるかもしれない。staticなプロパティのホストとしてenum
を利用することは、Swiftで名前空間を作成する標準的な手法である。空の列挙型はインスタンス化できないため enum を使う。
Itemを表示する画面と、そのプレビューコードを実装する
最後に通常のプロダクションコードで使用するSwiftUIのビューを定義する。前述した Item
を表示するだけの簡単な画面だ。#Preview
セクションで、PreviewItems.previewItem1
を使ってContentView
のプレビューを設定している。
import SwiftUI
struct ContentView: View {
let item: Item
var body: some View {
VStack {
Text(item.name)
}
.padding()
}
}
#Preview {
ContentView(
item: PreviewItems.previewItem1
)
}
プレビューを表示すると、下図のようにpreviewItem1
として定義したデータが表示される。
Preview Content に json ファイルを入れてプレビュー表示させる
また、プレビュー用のデータをJSONファイルで扱いたいケースもあるだろう。このセクションでは、Preview ContentにJSONファイルを入れてプレビューで表示させる方法を紹介する。
まず、JSONファイルをデシリアライズして利用できるように、Decodable を適合させる。
struct Item: Decodable {
let name: String
}
次に、preview_item.json
というファイルをPreview Content
グループの配下に配置する。内容は以下の通り。
{
"name": "jsonから読み込んだファイルだよ"
}
先ほど定義したPreviewItems
にpreviewItem2
を追加する。内部的には preview_item.json
を読み出して、JSONデータをデシリアライズしている。
enum PreviewItems {
static var previewItem2: Item {
loadJSON(fileName:"preview_item")
}
static func loadJSON(fileName: String) -> Item {
guard let url = Bundle.main.url(forResource: fileName, withExtension: "json") else {
fatalError("JSON file not found in Development Assets.")
}
do {
let data = try Data(contentsOf: url)
let decoder = JSONDecoder()
let item = try decoder.decode(Item.self, from: data)
return item
} catch {
fatalError("Failed to load or parse JSON: \(error)")
}
}
}
ContentViewのプレビューに使っていた item
を PreviewItems.previewItem2
を利用するように変更し、プレビューを表示すると下図のように表示される。
まとめ
Development Assetsを使ってSwiftUIのプレビューを表示する方法を紹介した。Development Assetsを使ってプレビュー専用のデータを管理する利点はいくつかある。
- プレビュー用データを専用のファイルに分離することで、コードの可読性と管理のしやすさが向上
#Preview
セクションで定義されたプレビューを使って、リアルタイムにデザインやレイアウトの確認ができるPreview Content
グループ内のデータは本番ビルドには含まれないため、リリース時のコードに影響を与えない
テスト用データとプロダクションコードが分離できることも嬉しいが、個人的にはアプリをアーカイブすると当該のファイルが除外されて、リリースビルドに含まれない点が一番好きだ。